/*
 * 
 *
 * Created on March 22, 2007, 12:34 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package edu.byu.isys413.samlam;
import java.util.*;
import java.io.*;
import java.sql.*;

/**
 * ConceptualDAO
 * @author Brian Barrett
 */
public class ConceptualDAO extends ProductDAO 
{
    
    
    /** Creates a new instance of ConceptualDAO */
    protected ConceptualDAO() {
        super();
    }
    /**
     * instantiate instance
     */
    protected static ConceptualDAO instance = null;
        
    /**
     * get instance
     * @return get instance
     */
    public static synchronized ConceptualDAO getInstance()
    {
        if (instance == null) {
            instance = new ConceptualDAO();
        }
        return instance;
    }
    
    /**
     * create
     * @return create
     */
    public Conceptual create()
    {
        Conceptual product = null;
        try {
            String id = GUID.generate();
            product = new Conceptual(id);
            Cache c = Cache.getInstance();
            c.put(product.getId(),product);
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return product;
    }
    
    /**
     * read
     * @param id id
     * @throws edu.byu.isys413.samlam.DataException exception
     * @throws edu.byu.isys413.samlam.ConnectionPoolException exception
     * @return read
     */
    public Conceptual read(String id) throws DataException,ConnectionPoolException
    {
        
        try
        {
            Connection conn = ConnectionPool.getInstance().get();
            Conceptual conceptual= read(id,conn);
            ConnectionPool.getInstance().release(conn);
            return conceptual;
        }
        catch (SQLException e)
        {
            // rollback
            throw new DataException("SQL error from read 1", e);
        }
        catch (ConnectionPoolException e)
        {
            throw new ConnectionPoolException("Connection pool error in read 1", e);
        }
    }
    
    /**
     * read
     * @param id id
     * @param conn conn
     * @throws java.sql.SQLException exception
     * @throws edu.byu.isys413.samlam.DataException exception
     * @throws edu.byu.isys413.samlam.ConnectionPoolException excpetion
     * @return read
     */
    public Conceptual read(String id, Connection conn) throws SQLException, DataException, ConnectionPoolException{
        Conceptual product = (Conceptual)Cache.getInstance().get(id);
        if(Cache.getInstance().containsKey(id)){
            
            return product;
            } 
                
           try{        
           PreparedStatement stmt = conn.prepareStatement("SELECT * FROM conceptual WHERE conceptualid=?");
           stmt.setString(1,id);
           ResultSet rs =  stmt.executeQuery();
           
           ConnectionPool.getInstance().release(conn);
            
            if (rs.next()) 
            {
                //Conceptual product = (Conceptual)ConceptualDAO.getInstance().create();
               
               Cache.getInstance().put(id,product);
                super.read(id);
                product.setId(rs.getString("conceptualID"));
                product.setDescription(rs.getString("Description"));
                product.setAvgcost(rs.getDouble("averageCost"));
                Cache.getInstance().put(id,product);      
                product.setObjectAlreadyInDB(true);
                stmt.close();
                return product;
               

            }
            else
            {
                throw new DataException("Product was not found in the database.");
            }
           
            }
           catch (ConnectionPoolException e)
           {
                throw new ConnectionPoolException("Could not retrieve a connection from the database", e);
            
            }
     catch (SQLException e){
                throw new DataException("SQL error", e);
            }
    }
    
    /**
     * save
     * @param prod product
     * @throws edu.byu.isys413.samlam.DataException exception
     * @throws edu.byu.isys413.samlam.ConnectionPoolException exception
     */
     public synchronized void save(Conceptual prod) throws DataException,ConnectionPoolException 
     {
           
        try
        {
            Connection conn = ConnectionPool.getInstance().get();
            save(prod,conn);
            ConnectionPool.getInstance().release(conn);
        }
        catch (SQLException e)
        {
            //rollback
            e.printStackTrace();
            //throw new DataException("Could not retrieve record for id=" + prod.getId(), e);
            
         }
        catch (ConnectionPoolException e)
        {
            //throw new ConnectionPoolException("Could not retrieve record for id=" + e);
                e.printStackTrace();
        }
        
        // release the connection back to the pool
        return;
    }
     synchronized void save(Conceptual prod, Connection conn) throws SQLException, DataException, ConnectionPoolException 
     {
        // check the dirty flag in the RevenueSourceDBO.  if it is dirty, 
        // run update or insert
        
        if (prod.isDirty()) 
        {
       
             if (prod.isObjectAlreadyInDB()) 
            {
               System.out.println("in the update ");
                update((Conceptual) prod, conn);
            }
            else
            {
               System.out.println("Entering insert of conceptual");
               insert(prod, conn);
               prod.setObjectAlreadyInDB(true);
            }
            
        Cache.getInstance().touch(prod.getId());
     
        }
        
    }

    private synchronized void update(Conceptual prod, Connection conn) throws SQLException, DataException, ConnectionPoolException
    {
        PreparedStatement stmt = conn.prepareStatement("UPDATE conceptual SET conceptualID=?,description=?,productName=?,averageCost=? WHERE conceptualid=? ");
        
        stmt.setString(1,prod.getId());
        stmt.setString(2,prod.getDescription());
        stmt.setString(3, prod.getProdname());        
        stmt.setDouble(4, prod.getAvgcost());
        stmt.setString(5,prod.getId());
        stmt.execute();
        stmt.close();
        super.save((Product)prod,conn);
        ConnectionPool.getInstance().release(conn);
        
    }
    private synchronized void insert(Conceptual prod, Connection conn) throws SQLException, DataException, ConnectionPoolException
    {
      
        PreparedStatement stmt = conn.prepareStatement("INSERT INTO conceptual VALUES ( ?,?,?,?)");
        
        Conceptual product = (Conceptual)prod;
        System.out.println(product.getId());
        stmt.setString(1,product.getId());
        System.out.println(product.getDescription());
        stmt.setString(2,product.getDescription());
        System.out.println(product.getProdname());
        stmt.setString(3, product.getProdname());
        System.out.println(product.getAvgcost());
        stmt.setDouble(4, product.getAvgcost());
        
        stmt.execute();
        super.save((Product)prod,conn);
        prod.setObjectAlreadyInDB(true);
        product.setObjectAlreadyInDB(true);
        stmt.close();
        // tell the RevenueSourceDBO that it's now in the db (so we call update next time not insert)
        
        ConnectionPool.getInstance().release(conn);
    }
}
